home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 April / macformat-023.iso / Shareware in MacFormat / LoadADrive1.1 / Source / LoadADrive.c next >
Encoding:
C/C++ Source or Header  |  1994-12-20  |  7.5 KB  |  398 lines  |  [TEXT/MPS ]

  1. // Source Code: (c) Dieter Spaar
  2.  
  3. // Freeware, but commercial use must be licensed
  4.  
  5. // Internet: spaar@mirider.abg.sub.org
  6.  
  7. // Dieter Spaar
  8. // Am Gerstenfeld 16
  9. // 86316 Friedberg
  10. // Germany
  11.  
  12.  
  13. // MPW version, use the following command:
  14.  
  15. // Rez LoadADrive.R -append -o LoadADrive
  16. // C LoadADrive.c -b -mbg on -sym on -opt off -warnings on -r
  17. // Link -sym on -l -t APPL -c 'DSLD' -msg dup,multiple,warn -ra %A5Init=resPreload,resLocked LoadADrive.C.o "{Libraries}"Runtime.o "{Libraries}"Interface.o "{CLibraries}"StdCLib.o -o LoadADrive > MAIN.MAP
  18. // SetFile -a Bi -d . -m . LoadADrive 
  19.  
  20.  
  21. #include     <Memory.h>
  22. #include     <Resources.h>
  23. #include    <Fonts.h>
  24. #include    <ToolUtils.h>
  25. #include    <Events.h>
  26. #include    <Windows.h>
  27. #include    <Dialogs.h>
  28. #include    <Controls.h>
  29. #include    <Packages.h>
  30. #include    <Menus.h>
  31. #include    <Strings.h>
  32. #include     <GestaltEqu.h>
  33. #include     <StandardFile.h>
  34. #include    <Aliases.h>
  35. #include    <Files.h>
  36. #include    <Devices.h>
  37. #include    <PLStringFuncs.h>
  38. #include     <StdArg.h>
  39. #include     <StdIO.h>
  40. #include     <StdLib.h>
  41.  
  42. /* some common constants */
  43.  
  44. #define TRUE    true
  45. #define FALSE    false
  46. #define NIL        nil
  47.  
  48. /* constants for compiler independency */
  49. /* here the MPW C-Compiler */
  50.  
  51. #define STATIC static
  52. #define EXTERN extern
  53. #define REGISTER register
  54. #define VOID void
  55. #define BYTE char
  56. #define WORD short
  57. #define LONG long
  58. #define BOOL Boolean
  59. #define UBYTE unsigned char
  60. #define UWORD unsigned short
  61. #define ULONG unsigned long
  62.  
  63. /* Resource */
  64.  
  65. /* ALRT */
  66.  
  67. #define ErrorAlert    128
  68.  
  69. /* alis */
  70.  
  71. #define INIT_ALIAS    128
  72.  
  73. /* STR */
  74.  
  75. #define DriverName    128
  76.  
  77. VOID eprintf(BYTE *format,...)
  78. {
  79.     BYTE buf[400];
  80.     va_list arg;
  81.     
  82.     va_start(arg,format);
  83.     vsprintf(buf,format,arg);
  84.     va_end(arg);
  85.     
  86.     c2pstr(buf);
  87.     ParamText(buf,"","","");
  88.     NoteAlert(ErrorAlert,NIL);
  89. }
  90.  
  91. /* get filename */
  92.  
  93. BOOL GetFilename(BYTE *name,WORD *vRefNum)
  94. {
  95.     Point where;
  96.     SFReply reply;
  97.     SFTypeList typeList;
  98.     
  99.     where.v=50;
  100.     where.h=70;
  101.     typeList[0]='INIT';
  102.     typeList[1]='cdev';
  103.     SFGetFile(where,"",NIL,2,typeList,NIL,&reply);
  104.     PLstrcpy(name,&reply.fName);
  105.     *vRefNum=reply.vRefNum;
  106.     
  107.     return reply.good;
  108. }
  109.  
  110. /* Create Alias of file and store it in the resource fork */
  111.  
  112. BOOL MakeMyAlias(VOID)
  113. {
  114.     WORD vRefNum;
  115.     Str63 fName;
  116.     FSSpec fSpec;
  117.     OSErr err;
  118.     AliasHandle alias;
  119.     Handle h;
  120.     
  121.     // get filename
  122.     
  123.     if( !GetFilename(fName,&vRefNum) )
  124.         return FALSE;
  125.  
  126.     // make FSSpec
  127.     
  128.     err=FSMakeFSSpec(vRefNum,0,fName,&fSpec);
  129.     if( err!=noErr ) {
  130.         eprintf("Error creating FSSpec.\n(err=%d)",err);
  131.         return FALSE;
  132.     }
  133.     
  134.     // create alias
  135.     
  136.     err=NewAlias(NIL,&fSpec,&alias);
  137.     if( err!=noErr ) {
  138.         eprintf("Error creating Alias.\n(err=%d)",err);
  139.         return FALSE;
  140.     }
  141.     
  142.     // delete old alias in resource
  143.     
  144.     SetResLoad(FALSE);
  145.     h=Get1Resource(rAliasType,INIT_ALIAS);
  146.     SetResLoad(TRUE);
  147.     
  148.     if(h!=NIL && ResError()==noErr) {
  149.         RmveResource(h);
  150.         err=ResError();
  151.         if( err!=noErr )
  152.             eprintf("Cannot remove old Alias from resource fork (maybe File/Drive protected).\n(err=%d)",err);
  153.     }
  154.     if(h!=NIL)
  155.         DisposHandle(h);
  156.         
  157.     // add alias to resource
  158.     
  159.     h=(Handle)alias;
  160.     AddResource(h,rAliasType,INIT_ALIAS,"\pInit");
  161.     err=ResError();
  162.     if(err!=noErr) {
  163.         eprintf("Error adding new Alias to resource fork.\n(err=%d)",err);
  164.         DisposHandle(h);
  165.         return FALSE;
  166.     }
  167.     UpdateResFile(CurResFile());
  168.     
  169.     err=ResError();
  170.     if(err!=noErr) {
  171.         eprintf("Error updating resource fork.\n(err=%d)",err);
  172.         ReleaseResource(h);
  173.         return FALSE;
  174.     }
  175.     ReleaseResource(h);
  176.  
  177.     return TRUE;
  178. }
  179.  
  180. /* Resolve file alias */
  181.  
  182. BOOL ResolveMyAlias(FSSpecPtr initFSSpec)
  183. {
  184.     Handle h;
  185.     OSErr err;
  186.     BOOL wasChanged;
  187.     
  188.     // get alias
  189.     
  190.     h=Get1Resource(rAliasType,INIT_ALIAS);
  191.     if( h==NIL ) {
  192.         eprintf("Cannot find Alias in resource fork.");
  193.         return FALSE;
  194.     }
  195.     
  196.     // resolve alias
  197.     
  198.     err=ResolveAlias(NIL,(AliasHandle)h,initFSSpec,&wasChanged);
  199.     if(err!=noErr) {
  200.         ReleaseResource(h);
  201.         eprintf("Cannot resolve Alias.\n(err=%d)",err);
  202.         return FALSE;
  203.     }
  204.     
  205.     // maybe update alias
  206.     
  207.     if( wasChanged ) {
  208.         ChangedResource(h);
  209.         UpdateResFile(CurResFile());
  210.         err=ResError();
  211.         if( err!=noErr )
  212.             eprintf("Cannot write back updated Alias.\n(err=%d)",err);
  213.     }
  214.     
  215.     ReleaseResource(h);
  216.     
  217.     return TRUE;
  218. }
  219.  
  220. /* check if a modifier key is pressed */
  221.  
  222. BOOL modifier(WORD mask)
  223. {
  224. #if 0 // does not work on some systems
  225.     EventRecord theEvent;
  226.     
  227.     EventAvail(everyEvent, &theEvent);
  228.     if( theEvent.modifiers & mask )
  229.         return TRUE;
  230.     else
  231.         return FALSE;
  232. #else
  233.     KeyMap theKeys;
  234.     int rotate = 0;
  235.     
  236.     GetKeys(theKeys);
  237.     switch(mask) {
  238.     case cmdKey:
  239.         rotate = 15;
  240.         break;
  241.     case optionKey:
  242.         rotate = 2;
  243.         break;
  244.     case controlKey:
  245.         rotate = 3;
  246.         break;
  247.     }
  248.     return ((theKeys[1] >> rotate) & 0x01) != 0; 
  249. #endif
  250. }
  251.  
  252. // this is the whole magic to load the Apple CD-ROM Driver
  253.  
  254. BOOL LoadInit(FSSpecPtr initFSSpec)
  255. {
  256.     WORD refNum,ret;
  257.     Handle hdl;
  258.     OSErr err;
  259.     BYTE name[50];
  260.     FInfo fndrInfo;
  261.     BOOL bIsCDEV = FALSE;
  262.     
  263.     // get driver name
  264.     
  265.     name[0]=0;
  266.     hdl=Get1Resource('STR ',DriverName);
  267.     if(hdl) {
  268.         PLstrcpy(name, *hdl);
  269.         ReleaseResource(hdl);
  270.     }
  271.     
  272.     // look for driver
  273.     
  274.     if(name[0])    {
  275.         if(OpenDriver(name,&refNum) == noErr) {
  276.             p2cstr(name);
  277.             eprintf("Driver '%s' already loaded.",name);
  278.             return FALSE;
  279.         }
  280.     }
  281.     
  282.     
  283.     // open resource fork
  284.     
  285.     refNum=FSpOpenResFile(initFSSpec, fsCurPerm);
  286.     err=ResError();
  287.     if(refNum == -1 || err!=noErr) {
  288.         eprintf("Cannot open file '%s'.\n(err=%d)", initFSSpec->name, err);
  289.         return FALSE;
  290.     }
  291.     
  292.     if( FSpGetFInfo(initFSSpec, &fndrInfo) == noErr)
  293.         bIsCDEV = fndrInfo.fdType == 'cdev';
  294.     
  295.     // load INIT into System Zone
  296.     
  297.     SetZone(SystemZone());
  298.     hdl=Get1IndResource('INIT',1);
  299.     if(hdl==0) { 
  300.         eprintf("Cannot load INIT from driver.");
  301.         SetZone(ApplicZone());
  302.         CloseResFile(refNum);
  303.         return FALSE;
  304.     }
  305.     HLock(hdl);
  306.     HNoPurge(hdl);
  307.  
  308.     // run INIT
  309.     
  310.     ret=(*(WORD(*)())(*hdl))();
  311.  
  312.     if(HGetState(hdl) & 0x20) // is it still a resource ? (don't unlock if detached)
  313.     {
  314.         HUnlock(hdl);
  315.         ReleaseResource(hdl);
  316.     }
  317.     SetZone(ApplicZone());    
  318.     CloseResFile(refNum);
  319.     
  320.     if(ret && !(bIsCDEV && ret == 3)) { // return code always 0 (3 for Spiritâ„¢ CD)?
  321.         eprintf("Cannot initialize Driver.\n(err=%d)",ret);
  322.         if(bIsCDEV)
  323.             PaintOne(nil, GetGrayRgn()); // redraw desktop
  324.         return FALSE;
  325.     }
  326.     
  327.     // look for driver
  328.     
  329.     if(name[0])    {
  330.         if(OpenDriver(name,&refNum) != noErr) {
  331.             p2cstr(name);
  332.             eprintf("Driver '%s' not loaded.",name);
  333.             if(bIsCDEV)
  334.                 PaintOne(nil, GetGrayRgn()); // redraw desktop
  335.             return FALSE;
  336.         }
  337.     }
  338.     
  339.     if(bIsCDEV)
  340.         PaintOne(nil, GetGrayRgn()); // redraw desktop
  341.  
  342.     return TRUE;
  343. }
  344.  
  345. main()
  346. {
  347.     Handle hdl;
  348.     FSSpec initFSSpec;
  349.     LONG gesResponse;
  350.     
  351.     // initialisation
  352.     
  353.     MaxApplZone();    
  354.     InitGraf(&qd.thePort);
  355.     InitFonts();
  356.     FlushEvents(everyEvent, 0);
  357.     InitWindows();
  358.     InitMenus();
  359.     TEInit();
  360.     InitDialogs(nil);
  361.     InitCursor();
  362.         
  363.     // check for essential Mangers
  364.     
  365.     if ( Gestalt (gestaltFSAttr, &gesResponse) || !BitTst(&gesResponse,31 - gestaltFullExtFSDispatching) ||
  366.      !BitTst(&gesResponse,31 - gestaltHasFSSpecCalls) ||
  367.      Gestalt (gestaltAliasMgrAttr, &gesResponse) || !BitTst(&gesResponse,31 - gestaltAliasMgrPresent) ) {
  368.          eprintf("You need the Alias Manager and the File Manager for 'LoadADrive' to run.");
  369.         return;
  370.     }
  371.     
  372.     // command key down: always ask for file
  373.     
  374.     if(modifier(cmdKey))
  375.         hdl=NIL;
  376.     else
  377.         hdl=Get1Resource(rAliasType,INIT_ALIAS);
  378.     if( hdl==NIL ) {
  379.         eprintf("LoadADrive V 1.1\n\nFreeware by Dieter Spaar\nCommercial use must be licensed.\nInterNet: spaar@mirider.abg.sub.org");
  380.         eprintf("Mount CD-ROM without Restart. Select the CD-ROM Driver now.");
  381.         if(!MakeMyAlias())
  382.             return;
  383.     }
  384.     else
  385.         ReleaseResource(hdl);
  386.     
  387.     // get FSSPec of file
  388.     
  389.     while(!ResolveMyAlias(&initFSSpec)) {
  390.         eprintf("Select the CD-ROM Driver now.");
  391.         if(!MakeMyAlias())
  392.             return;
  393.     }
  394.     
  395.     // and now load the file
  396.     
  397.     LoadInit(&initFSSpec);
  398. }